In C++ you can give special meanings to operators, when they are used with user-defined classes and this is called
operator overloading. You can implement C++ operator overloads by providing
special member-functions on your classes that follow a particular naming convention. For example, to overload the + operator for your class, you would provide a member-function named operator+ on your class.
The following set of operators is commonly overloaded for user-defined classes:
- = (assignment operator)
- + - * (binary arithmetic operators)
- += -= *= (compound assignment operators)
- == != (comparison operators)
Here are some guidelines for implementing these operators. These guidelines are very important to follow.
Assignment Operator =
The assignment operator has a signature like this:
class MyClass {
public:
...
MyClass & operator=(const MyClass & rhs);
...
}
MyClass a, b;
...
b = a; // Same as b.operator=(a);
Notice that the = operator takes a const-reference to the right hand side of the assignment. The reason for this should be obvious, since we don't want to change that value; we only want to change what is on the left hand side.
Also, you will notice that a reference is returned by the assignment operator. This is to allow operator chaining. You typically see it with primitive types, like this:
int a, b, c, d, e;
a = b = c = d = e = 42;
This is interpreted by the compiler as:
a = (b = (c = (d = (e = 42))));
In other words, assignment is right-associative. The last assignment operation is evaluated first, and is propagated leftward through the series of assignments. Specifically: e = 42 assigns 42 to e, then returns e as the result
- The value of e is then assigned to d, and then d is returned as the result
- The value of d is then assigned to c, and then c is returned as the result
Now, in order to support operator chaining, the assignment operator must return some value. The value that should be returned is a reference to the left-hand side of the assignment.
Notice that the returned reference is not declared const. This can be a bit confusing, because it allows you to write crazy stuff like this:
MyClass a, b, c;
...
(a = b) = c; //
At first glance, you might want to prevent situations like this, by having operator= return a const reference.
However, statements like this will work with primitive types.
It is important to return a non-const reference from your operator=.
General Rule: If it is good enough for ints, then it is good enough for user-defined data-types.